﻿using System;
using System.Collections.Generic;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.FileProviders.Composite;
using Microsoft.Extensions.Primitives;

namespace VirtualFileSystem
{
    public abstract class AbsDictionaryFileProvider : IFileProvider
    {
        protected abstract IDictionary<string, IFileInfo> Files { get; }

        public virtual IFileInfo GetFileInfo(string subpath)
        {
            if (subpath == null)
            {
                return new NotFoundFileInfo(subpath);
            }
            if (Files.TryGetValue(subpath.ToLower(), out var fileInfo) == false)
            {
                return new NotFoundFileInfo(subpath);
            }
            return fileInfo;
        }

        public virtual IDirectoryContents GetDirectoryContents(string subpath)
        {
            var directoryPath = subpath.ToLower();
            if (directoryPath.EndsWith('/') == false) directoryPath += '/';

            var directory = GetFileInfo(directoryPath);
            if (!directory.IsDirectory)
            {
                return NotFoundDirectoryContents.Singleton;
            }
            var fileList = new List<IFileInfo>();
            foreach (var fileInfo in Files)
            {
                if (fileInfo.Key.StartsWith(directoryPath))
                {
                    if (fileInfo.Key == directoryPath) continue;
                    var childDirectoryIndex=fileInfo.Key.IndexOf('/', directoryPath.Length);
                    if (childDirectoryIndex > -1 && childDirectoryIndex != fileInfo.Key.Length - 1) continue;
                    fileList.Add(fileInfo.Value);
                }
            }

            return new VirtualDirectoryContents(fileList.GetEnumerator());
        }

        public virtual IChangeToken Watch(string filter)
        {
            return NullChangeToken.Singleton;
        }

        protected virtual string NormalizePath(string subpath)
        {
            return subpath;
        }
    }
}
